#include "ExternComm.h"
#include "DataProcess.h"
#include "Seed_Driver.h"
#include "hx6203sys.h"
#include "PA_Driver.h"
#include "AMP_Driver.h"
#include <stdlib.h>
#include <stdio.h>
#include "delay.h"
#include "sys.h"

//电源键置位标志
extern uint8_t Power_Key;
//设定功率
extern uint16_t PowerSetValue;
//功率设置标志
extern uint8_t P_SetFlag;

uint16_t Extern485_UART_Count=0;	//串口计数
uint8_t Extern485_UART_Finish=0;
uint8_t Extern485_UART_BUF[64];

struct RUN_TIME
{
    uint16_t h;
    uint8_t m;
    uint8_t s;
};

//系统反馈信息
extern struct HX6203_StateType HX6203;
extern struct Seed_StateType Seed;
extern unsigned int HX6203_Protect;
extern uint8_t NodeState[11];
//功率自动调整标志
extern enum SwitchType PID_LOCK;
extern struct RUN_TIME RunTime;

//判断INTL_RS485是否接收到数据
//如果已接收，将数据解析
uint8_t Extern_UART_GetData(void){
	//未接收
	if(Extern485_UART_Finish==0) return 0;

    float vbias;

	//已经接收
	if(Extern485_UART_BUF[0] == 0x01)	//工业屏控制接口
    {
        if(CRC_Check(Extern485_UART_BUF, Extern485_UART_Count))
        {
			HX6203.ControlBit = 1;	// 开启工业屏控制位
            switch(Extern485_UART_BUF[1])
            {
                case 0x01:  //查询状态
                    Extern485_UART_BUF[2] = 0x04;
                    Extern485_UART_BUF[3] = HX6203.StateBit;
                    Extern485_UART_BUF[4] = HX6203.StateBit >> 8;
                    Extern485_UART_BUF[5] = HX6203.StateBit >> 16;
                    Extern485_UART_BUF[6] = HX6203.StateBit >> 24;
                    ModbusCRC16(Extern485_UART_BUF, 7);
                    UART4_SendArray(Extern485_UART_BUF, 9);
                break;
                case 0x03:  //查询数据
                    if(Extern485_UART_BUF[3] == 65) //查询功率
                    {
                        Extern485_UART_BUF[2] = 0x02;
//                        PowerSetValue = (uint16_t)Extern485_UART_BUF[4] << 8;   //取高八位
//                        PowerSetValue |= (uint16_t)Extern485_UART_BUF[5];       //取第八位
                        ModbusCRC16(Extern485_UART_BUF, 6);
                        UART4_SendArray(Extern485_UART_BUF, 8);
                    }
                    else
                    {
                        Extern485_UART_BUF[2] = 0x10;
                        Extern485_UART_BUF[3] = (uint16_t)(Seed.Vbias * 10) >> 8;
                        Extern485_UART_BUF[4] = (uint16_t)(Seed.Vbias * 10);
                        Extern485_UART_BUF[5] = (uint16_t)(Seed.Curr * 10) >> 8;
                        Extern485_UART_BUF[6] = (uint16_t)(Seed.Curr * 10);
                        Extern485_UART_BUF[7] = (uint16_t)(HX6203.PATempMax * 10) >> 8;
                        Extern485_UART_BUF[8] = (uint16_t)(HX6203.PATempMax * 10);
                        Extern485_UART_BUF[9] = (uint16_t)(HX6203.PATempMin * 10) >> 8;
                        Extern485_UART_BUF[10] = (uint16_t)(HX6203.PATempMin * 10);
                        Extern485_UART_BUF[11] = (uint16_t)HX6203.FwdMap >> 8;
                        Extern485_UART_BUF[12] = (uint16_t)HX6203.FwdMap;
                        Extern485_UART_BUF[13] = (uint16_t)HX6203.RevRF >> 8;
                        Extern485_UART_BUF[14] = (uint16_t)HX6203.RevRF;
                        Extern485_UART_BUF[15] = 0x00;
                        Extern485_UART_BUF[16] = 0x00;
                        Extern485_UART_BUF[17] = 0x00;
                        Extern485_UART_BUF[18] = 0x00;
                        ModbusCRC16(Extern485_UART_BUF, 19);
                        UART4_SendArray(Extern485_UART_BUF, 21);
                    }
                    break;
                case 0x05:  //开关机
                    if(Extern485_UART_BUF[3] == 0x02)
                    {
                        if(Extern485_UART_BUF[4])   //开机
                            HX6203.STA = ON;
                        else
                            HX6203.STA = OFF;
                        Power_Key = 1;
                        UART4_SendArray(Extern485_UART_BUF, 8);
                    }
                    break;
                case 0x06:  //设定功率
                    if(HX6203.STA == ON)
                    {
                        PowerSetValue = (uint16_t)Extern485_UART_BUF[4] << 8;   //取高八位
                        PowerSetValue |= (uint16_t)Extern485_UART_BUF[5];       //取第八位
						if(HX6203.EEPROMdata.fwdRFratio > 0)
							PowerSetValue *= HX6203.EEPROMdata.fwdRFratio;			//工业屏设定功率映射
                        if(PowerSetValue > P_UpLimit) PowerSetValue = P_UpLimit;
                        P_SetFlag = 1;  //开启功率设置
                        UART4_SendArray(Extern485_UART_BUF, 8);
                    }
                    break;
            }
        }
    }
	else if(Extern485_UART_BUF[0] == 0x66)	//调试接口
	{
		if(dataCheck(Extern485_UART_BUF, Extern485_UART_Count-1) == 0) {
			//校验通过 开始解析
			switch(Extern485_UART_BUF[1]){
				case 0x00:  //清空系统错误信息并重新计时
                    if(Extern485_UART_BUF[2]==0x00)
                    {
                        HX6203_Protect = 0;
                        for(uint8_t i=0; i<11; i++)
                        {
                            NodeState[i] = 0;
                        }
                        RunTime.h = 0;
                        RunTime.m = 0;
                        RunTime.s = 0;
                    }
                    break;
				case 0x01:	//前放PD
					if(Extern485_UART_BUF[2]==0x00){ //关PD
						GPIO_ResetBits(GPIOA,GPIO_Pin_5);	//PA5置低
						Seed.PD=0;
						setPAElementPower(0x00,0x00);
						delay_ms(20);
						setPAElementPower(0x01,0x00);
					}
					else
                    {
						GPIO_SetBits(GPIOA,GPIO_Pin_5);	//PA5置高
						Seed.PD=1;
						setPAElementPower(0x00,0x01);
						delay_ms(20);
						setPAElementPower(0x01,0x01);
					}
					break;

				case 0x02: //种子源偏置电压
					Seed.Vbias = *(float *)&Extern485_UART_BUF[2];
					//if(Seed.Vbias > 1.6f) Seed.Vbias = 1.6f; 
					Seed.Vbias = Seed_SetVlotage(Seed.Vbias);
					break;

				case 0x03:	//前放栅压
					vbias=((float)Extern485_UART_BUF[2]*0.1f)-5.0f;
					setPAElementVoltage(0,vbias);
					delay_ms(5);
					setPAElementVoltage(1,vbias);
					break;
				case 0x04:	//Aim临时测试
					SetAmpAimRF(0,Extern485_UART_BUF[2]);
					break;
                case 0x05:  //开关pid
                    if(Extern485_UART_BUF[2] == 0x01)   PID_LOCK = ON;
                    else PID_LOCK = OFF;
                    break;
                case 0x06:  //打印整机状态 配合调试助手
                    printf("Equipment state\n"
                            "PD: %d Drive: %.2fV\n"
                            "PA1 I: %.2fA T: %.2fC\n"
                            "PA2 I: %.2fA T: %.2fC\n"
                            "FwdP: %.2fW RevP: %.2fW\n"
							"T : |%.1f|%.1f|%.1f|%.1f|%.1f|%.1f|%.1f|%.1f|%.1f|\n"
                            "P+: |%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|\n"
                            "P-: |%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|%.0f|\n",
                            Seed.PD, Seed.Vbias,
                            HX6203.Preamp[0].Curr, HX6203.Preamp[0].Temp,
                            HX6203.Preamp[1].Curr, HX6203.Preamp[1].Temp,
                            HX6203.FwdRF, HX6203.RevRF,
							HX6203.AMP[0].MaxTemp, HX6203.AMP[1].MaxTemp, HX6203.AMP[2].MaxTemp, HX6203.AMP[3].MaxTemp, HX6203.AMP[4].MaxTemp, HX6203.AMP[5].MaxTemp, HX6203.AMP[6].MaxTemp, HX6203.AMP[7].MaxTemp, HX6203.AMP[8].MaxTemp,
                            HX6203.AMP[0].FwdRF, HX6203.AMP[1].FwdRF, HX6203.AMP[2].FwdRF, HX6203.AMP[3].FwdRF, HX6203.AMP[4].FwdRF, HX6203.AMP[5].FwdRF, HX6203.AMP[6].FwdRF, HX6203.AMP[7].FwdRF, HX6203.AMP[8].FwdRF,
                            HX6203.AMP[0].RevRF, HX6203.AMP[1].RevRF, HX6203.AMP[2].RevRF, HX6203.AMP[3].RevRF, HX6203.AMP[4].RevRF, HX6203.AMP[5].RevRF, HX6203.AMP[6].RevRF, HX6203.AMP[7].RevRF, HX6203.AMP[8].RevRF);
                    break;
                case 0x07:  //设置刀片栅压
                    break;
				case 0x08:	//整机开机
					if(Extern485_UART_BUF[2])
						HX6203.STA = ON;
					else
						HX6203.STA = OFF;
					Power_Key = 1;
					break;
				case 0x09:
					if(HX6203.STA == ON)
                    {
                        PowerSetValue = (uint16_t)Extern485_UART_BUF[2] << 8;   //取高八位
                        PowerSetValue |= (uint16_t)Extern485_UART_BUF[3];       //取第八位
                        if(PowerSetValue > P_UpLimit) PowerSetValue = P_UpLimit;
						P_SetFlag = 1;  //开启功率设置
                    }
					break;
                case 0x0a:
                    if(Extern485_UART_BUF[2])
                        HX6203.DebugMode = 1;
                    else
                        HX6203.DebugMode = 0;
                    break;
				case 0x0b:	//打印编译日期
					printf("HX6203 %s %s\n", __DATE__, __TIME__);
					break;
			}
		}
	}
	else if(Extern485_UART_BUF[0] == 0x33)	//系统参数设置接口
	{
		if(dataCheck(Extern485_UART_BUF, Extern485_UART_Count-1) == 0)
		{
			dataTypeChange_t data;
			switch(Extern485_UART_BUF[1])
			{
				case 0:	//查询参数
					printf("\nControlBit: %d\n"
							"System parameter:\n"
							"ampGateVoltage: %.2f\n"
							"fwdRFratio: %.2f\n"
							"pMapValue: %d\n"
							"pProtect: %d\n",
							HX6203.ControlBit,
							HX6203.EEPROMdata.ampGateVoltage,
							HX6203.EEPROMdata.fwdRFratio,
							HX6203.EEPROMdata.pMapValue,
							HX6203.EEPROMdata.pProtect);
					break;
				case 1: //保存参数
					EEPROM_ContinuousWrite(EE_DATA_START, (uint8_t *)&HX6203.EEPROMdata, sizeof(eeprom_data_t));
					printf("\nOK\n");
					break;
				case 2: //设置ampGateVoltage
					data.fot = *(float *)&Extern485_UART_BUF[2];
					if(fabs(data.fot - AMP_GateVoltage) <= 3)
					{
						memcpy(&HX6203.EEPROMdata.ampGateVoltage, &Extern485_UART_BUF[2], sizeof(float));
						HX6203.AMP_GateV_Flag = 1;
					}
					break;
				case 3:
					data.fot = *(float *)&Extern485_UART_BUF[2];
					if(fabs(data.fot) <= 2)
						memcpy(&HX6203.EEPROMdata.fwdRFratio, &Extern485_UART_BUF[2], sizeof(float));
					break;
				case 4:
					data.u16[0] = *(uint16_t *)&Extern485_UART_BUF[2];
					if(abs(data.u16[0] - P_MapValue) <= 2000)
						memcpy(&HX6203.EEPROMdata.pMapValue, &Extern485_UART_BUF[2], sizeof(uint16_t));
					break;
				case 5:
					data.u16[0] = *(uint16_t *)&Extern485_UART_BUF[2];
					if(abs(data.u16[0] - P_Protect_Debug) <= 2000)
						memcpy(&HX6203.EEPROMdata.pProtect, &Extern485_UART_BUF[2], sizeof(uint16_t));
					break;
			}
		}
	}
	//已经接收
	Extern485_UART_Count=0;
	Extern485_UART_Finish=0;
	return 1;
}



void Extern485_Init(uint32_t bound){
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);

	//串口3对应引脚复用映射
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_UART4);
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_UART4);

	//UART4端口配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure);

   //UART4 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
	USART_Init(UART4, &USART_InitStructure); //初始化串口1

	USART_ITConfig(UART4,USART_IT_RXNE, ENABLE);//开启接收中断
	USART_ITConfig(UART4,USART_IT_IDLE, ENABLE);//开启空闲中断

	//USART4 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;//串口4中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	USART_Cmd(UART4, ENABLE);  //使能串口4
}

void UART4_SendArray(uint8_t *Array, uint16_t Length)
{
    for(uint16_t i=0; i<Length; i++)
    {
        USART_SendData(UART4, Array[i]);
        while (USART_GetFlagStatus(UART4, USART_FLAG_TXE) == RESET);
    }
}

void UART4_IRQHandler(void)                	//串口4中断服务程序
{
	uint8_t Res;
	if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)  //接收到一个字节
	{
		Res =USART_ReceiveData(UART4);//读取1Byte
		if(Extern485_UART_Finish==0)//接收未完成
		{
			Extern485_UART_BUF[Extern485_UART_Count]=Res ;
			Extern485_UART_Count++;
		}
  }
	else if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET)	//接收完成一帧
	{
		Res=UART4->SR;
		Res=UART4->DR;
		Extern485_UART_Finish=1;	//接收完成了
	}
}
